﻿2026-05-16T05:04:51.3313939Z ##[group]Run pnpm verify:phase-4
2026-05-16T05:04:51.3314328Z [36;1mpnpm verify:phase-4[0m
2026-05-16T05:04:51.3349284Z shell: /usr/bin/bash -e {0}
2026-05-16T05:04:51.3349590Z env:
2026-05-16T05:04:51.3349844Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-16T05:04:51.3350499Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-16T05:04:51.3350750Z   SKIP_TRACE_CHECK: 1
2026-05-16T05:04:51.3350968Z ##[endgroup]
2026-05-16T05:04:51.6650818Z 
2026-05-16T05:04:51.6651921Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-16T05:04:51.6659467Z > node scripts/verify-phase-4.mjs
2026-05-16T05:04:51.6660371Z 
2026-05-16T05:04:51.7129777Z 
2026-05-16T05:04:51.7146233Z === Workspace: typecheck ===
2026-05-16T05:04:51.7147262Z >>> pnpm -r typecheck
2026-05-16T05:04:52.0701220Z Scope: 5 of 6 workspace projects
2026-05-16T05:04:52.0763886Z packages/db typecheck$ tsc --noEmit
2026-05-16T05:04:52.0773171Z packages/game-logic typecheck$ tsc --noEmit
2026-05-16T05:04:54.8331619Z packages/game-logic typecheck: Done
2026-05-16T05:04:54.8364978Z packages/protocol typecheck$ tsc --noEmit
2026-05-16T05:04:57.1337425Z packages/db typecheck: Done
2026-05-16T05:04:58.5289142Z packages/protocol typecheck: Done
2026-05-16T05:04:58.5295530Z apps/client typecheck$ tsc --noEmit
2026-05-16T05:04:58.5298936Z apps/server typecheck$ tsc --noEmit
2026-05-16T05:05:11.5431354Z apps/client typecheck: Done
2026-05-16T05:05:12.1522474Z apps/server typecheck: Done
2026-05-16T05:05:12.1631007Z 
2026-05-16T05:05:12.1631790Z === Lint: protocol-sync ===
2026-05-16T05:05:12.1645967Z >>> pnpm lint:protocol-sync
2026-05-16T05:05:12.4876706Z 
2026-05-16T05:05:12.4877858Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-16T05:05:12.4881144Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-16T05:05:12.4881585Z 
2026-05-16T05:05:12.5208191Z lint-protocol-sync: OK
2026-05-16T05:05:12.5346023Z 
2026-05-16T05:05:12.5347171Z === Lint: game-logic-purity ===
2026-05-16T05:05:12.5348721Z >>> pnpm lint:game-logic-purity
2026-05-16T05:05:12.8572951Z 
2026-05-16T05:05:12.8574039Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-16T05:05:12.8575743Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-16T05:05:12.8576533Z 
2026-05-16T05:05:12.8891300Z lint-game-logic-purity: OK (8 file(s) clean)
2026-05-16T05:05:12.9014820Z 
2026-05-16T05:05:12.9015715Z === Lint: better-auth-schema-sync ===
2026-05-16T05:05:12.9017892Z >>> pnpm lint:better-auth-schema-sync
2026-05-16T05:05:13.2271958Z 
2026-05-16T05:05:13.2291455Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-16T05:05:13.2297888Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-16T05:05:13.2301333Z 
2026-05-16T05:05:14.9582496Z lint-better-auth-schema-sync: OK
2026-05-16T05:05:14.9713945Z 
2026-05-16T05:05:14.9714811Z === Lint: rate-limit-budgets ===
2026-05-16T05:05:14.9715697Z >>> pnpm lint:rate-limit-budgets
2026-05-16T05:05:15.2961563Z 
2026-05-16T05:05:15.2962680Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-16T05:05:15.2963992Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-16T05:05:15.2964710Z 
2026-05-16T05:05:15.3274086Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-16T05:05:15.3412630Z 
2026-05-16T05:05:15.3413559Z === Lint: no-clipboard-rce ===
2026-05-16T05:05:15.3414546Z >>> pnpm lint:no-clipboard-rce
2026-05-16T05:05:15.6636364Z 
2026-05-16T05:05:15.6637488Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-16T05:05:15.6638821Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-16T05:05:15.6639525Z 
2026-05-16T05:05:15.7008672Z lint-no-clipboard-rce: OK (22 file(s) clean)
2026-05-16T05:05:15.7147000Z 
2026-05-16T05:05:15.7147838Z === Lint: room-layout ===
2026-05-16T05:05:15.7148778Z >>> pnpm lint:room-layout
2026-05-16T05:05:16.0479226Z 
2026-05-16T05:05:16.0480617Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-16T05:05:16.0481895Z > node tools/scripts/lint-room-layout.mjs
2026-05-16T05:05:16.0483160Z 
2026-05-16T05:05:16.0846124Z lint-room-layout: OK
2026-05-16T05:05:16.0975948Z 
2026-05-16T05:05:16.0976607Z === ADR 0004 lint ===
2026-05-16T05:05:16.0977416Z >>> pnpm lint:adr:0004
2026-05-16T05:05:16.4127512Z 
2026-05-16T05:05:16.4128615Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-16T05:05:16.4130445Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-16T05:05:16.4131496Z 
2026-05-16T05:05:16.4437904Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-16T05:05:16.4560742Z 
2026-05-16T05:05:16.4561542Z === Drizzle: emit-check ===
2026-05-16T05:05:16.4562313Z >>> pnpm db:emit-check
2026-05-16T05:05:16.8020202Z 
2026-05-16T05:05:16.8021501Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-16T05:05:16.8024779Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-16T05:05:16.8027112Z 
2026-05-16T05:05:17.2730744Z No config path provided, using default 'drizzle.config.ts'
2026-05-16T05:05:17.2733435Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-16T05:05:17.7211774Z 8 tables
2026-05-16T05:05:17.7212650Z accounts 8 columns 1 indexes 0 fks
2026-05-16T05:05:17.7213622Z audit_log 6 columns 0 indexes 2 fks
2026-05-16T05:05:17.7214635Z characters 9 columns 0 indexes 1 fks
2026-05-16T05:05:17.7218348Z inventory_items 4 columns 0 indexes 1 fks
2026-05-16T05:05:17.7219405Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-16T05:05:17.7220707Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-16T05:05:17.7221625Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-16T05:05:17.7222402Z sessions 5 columns 0 indexes 1 fks
2026-05-16T05:05:17.7222921Z 
2026-05-16T05:05:17.7223829Z No schema changes, nothing to migrate 😴
2026-05-16T05:05:18.3972458Z 
2026-05-16T05:05:18.3973374Z === Drizzle: schema-sync ===
2026-05-16T05:05:18.3974269Z >>> pnpm lint:schema-sync
2026-05-16T05:05:18.7207231Z 
2026-05-16T05:05:18.7208141Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-16T05:05:18.7211619Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-16T05:05:18.7213810Z 
2026-05-16T05:05:18.7523505Z OK
2026-05-16T05:05:18.7661163Z 
2026-05-16T05:05:18.7662029Z === Drizzle: source-comments ===
2026-05-16T05:05:18.7662852Z >>> pnpm lint:source-comments
2026-05-16T05:05:19.0911780Z 
2026-05-16T05:05:19.0913120Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-16T05:05:19.0914353Z > pnpm -C packages/db run lint:source-comments
2026-05-16T05:05:19.0915002Z 
2026-05-16T05:05:19.4229837Z 
2026-05-16T05:05:19.4231468Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-16T05:05:19.4232873Z > node scripts/check-source-comments.mjs
2026-05-16T05:05:19.4233574Z 
2026-05-16T05:05:19.4572644Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-16T05:05:19.4813581Z 
2026-05-16T05:05:19.4814593Z === Workspace: test ===
2026-05-16T05:05:19.4815385Z >>> pnpm -r test
2026-05-16T05:05:19.8064689Z Scope: 5 of 6 workspace projects
2026-05-16T05:05:19.8126463Z packages/db test$ vitest run
2026-05-16T05:05:19.8136178Z packages/game-logic test$ vitest run
2026-05-16T05:05:20.3279433Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-16T05:05:20.3663994Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-16T05:05:20.8012769Z packages/game-logic test:  [32m✓[39m test/step-bno-fidelity.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-16T05:05:21.0431098Z packages/game-logic test:  [32m✓[39m test/collision-axis-slide.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T05:05:21.2645081Z packages/game-logic test:  [32m✓[39m test/wall-slide.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:21.4395174Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T05:05:21.5229039Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T05:05:21.7088612Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T05:05:21.7638785Z packages/game-logic test:  [32m✓[39m test/walkable-edge.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T05:05:22.0117627Z packages/game-logic test:  [32m✓[39m test/movement-constants.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:22.2332780Z packages/game-logic test:  [32m✓[39m test/sprite-state-machine.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T05:05:22.4623346Z packages/game-logic test:  [32m✓[39m test/navi-mask-bbox.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T05:05:22.5574194Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T05:05:22.5671914Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-16T05:05:22.5711702Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-16T05:05:22.5731164Z packages/db test: [2m   Start at [22m 05:05:20
2026-05-16T05:05:22.5761835Z packages/db test: [2m   Duration [22m 2.19s[2m (transform 192ms, setup 0ms, import 1.49s, tests 32ms, environment 1ms)[22m
2026-05-16T05:05:22.6080893Z packages/db test: Done
2026-05-16T05:05:22.6111133Z packages/protocol test$ vitest run
2026-05-16T05:05:22.7298731Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-16T05:05:23.0012822Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:23.1347692Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-16T05:05:23.2469592Z packages/game-logic test:  [32m✓[39m test/run-speed.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T05:05:23.4937878Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T05:05:23.5092326Z packages/game-logic test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T05:05:23.5093952Z packages/game-logic test: [2m      Tests [22m [1m[32m60 passed[39m[22m[90m (60)[39m
2026-05-16T05:05:23.5111185Z packages/game-logic test: [2m   Start at [22m 05:05:20
2026-05-16T05:05:23.5129039Z packages/game-logic test: [2m   Duration [22m 3.17s[2m (transform 277ms, setup 0ms, import 528ms, tests 120ms, environment 2ms)[22m
2026-05-16T05:05:23.5806223Z packages/game-logic test: Done
2026-05-16T05:05:23.6357779Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T05:05:23.8156481Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T05:05:23.9998851Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:24.1607198Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:24.1648235Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-16T05:05:24.1669231Z packages/protocol test: [2m      Tests [22m [1m[32m36 passed[39m[22m[90m (36)[39m
2026-05-16T05:05:24.1671288Z packages/protocol test: [2m   Start at [22m 05:05:23
2026-05-16T05:05:24.1673282Z packages/protocol test: [2m   Duration [22m 1.02s[2m (transform 157ms, setup 0ms, import 295ms, tests 38ms, environment 0ms)[22m
2026-05-16T05:05:24.1960812Z packages/protocol test: Done
2026-05-16T05:05:24.1966460Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-16T05:05:24.1968976Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-16T05:05:24.7414528Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-16T05:05:24.8462428Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-16T05:05:25.3522298Z apps/server test:  [32m✓[39m test/layout-derive.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 116[2mms[22m[39m
2026-05-16T05:05:26.5827859Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 123[2mms[22m[39m
2026-05-16T05:05:26.8761271Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T05:05:26.9761215Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-16T05:05:26.9802163Z apps/client test: [22m[39mroom_layout signature did not verify — rendering anyway (defense-in-depth; see 06.1-D40-SPIKE.md) mvp-lobby 000
2026-05-16T05:05:27.0621716Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 266[2mms[22m[39m
2026-05-16T05:05:27.1342790Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 23[2mms[22m[39m
2026-05-16T05:05:27.4716182Z apps/server test: {"level":40,"time":1778907927468,"pid":3342,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T05:05:27.4806328Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T05:05:27.4911993Z apps/server test: {"level":40,"time":1778907927472,"pid":3342,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T05:05:27.4971723Z apps/server test: {"level":40,"time":1778907927473,"pid":3342,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T05:05:28.3673774Z apps/server test: {"level":30,"time":1778907928365,"pid":3366,"hostname":"runnervmrw5os","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-16T05:05:28.3701727Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 670[2mms[22m[39m
2026-05-16T05:05:28.3721528Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 576[2mms[22m[39m
2026-05-16T05:05:28.5226248Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.teleport-gate.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 125[2mms[22m[39m
2026-05-16T05:05:29.3028430Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-16T05:05:29.3036901Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-FbjcPT/rebno.db
2026-05-16T05:05:29.3041133Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T05:05:29.3051924Z apps/server test: [run-migrations] OK
2026-05-16T05:05:29.3132997Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-16T05:05:29.3144259Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-1tE8jh/rebno.db
2026-05-16T05:05:29.3147130Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T05:05:29.3152846Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-16T05:05:29.3167455Z apps/server test: [run-migrations] OK
2026-05-16T05:05:29.3242515Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T05:05:29.3257412Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-TAYQaY/rebno.db
2026-05-16T05:05:29.3261121Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T05:05:29.3264442Z apps/server test: [run-migrations] OK
2026-05-16T05:05:29.3280753Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T05:05:29.3291535Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-TAYQaY/rebno.db
2026-05-16T05:05:29.3309542Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T05:05:29.3331041Z apps/server test: [run-migrations] OK
2026-05-16T05:05:29.3361909Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 53[2mms[22m[39m
2026-05-16T05:05:29.6575691Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 20[2mms[22m[39m
2026-05-16T05:05:29.7422915Z apps/client test:  [32m✓[39m src/__test__/nameplate-stability.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 27[2mms[22m[39m
2026-05-16T05:05:29.8991252Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T05:05:30.2486393Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 28[2mms[22m[39m
2026-05-16T05:05:30.4902194Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:30.9676303Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 81[2mms[22m[39m
2026-05-16T05:05:31.3586556Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-16T05:05:31.3632526Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ multiple files { path: ['.env.local', '.env'] }
2026-05-16T05:05:31.3671370Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-16T05:05:32.1153830Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T05:05:32.1271760Z apps/server test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T05:05:32.1311384Z apps/server test: [2m      Tests [22m [1m[32m71 passed[39m[22m[90m (71)[39m
2026-05-16T05:05:32.1331072Z apps/server test: [2m   Start at [22m 05:05:24
2026-05-16T05:05:32.1332879Z apps/server test: [2m   Duration [22m 7.37s[2m (transform 576ms, setup 0ms, import 3.66s, tests 1.09s, environment 2ms)[22m
2026-05-16T05:05:32.1438551Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 18[2mms[22m[39m
2026-05-16T05:05:32.1674379Z apps/server test: Done
2026-05-16T05:05:32.8597618Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T05:05:33.6239014Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m16 tests[22m[2m)[22m[32m 76[2mms[22m[39m
2026-05-16T05:05:34.3950597Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-16T05:05:35.1243456Z apps/client test:  [32m✓[39m src/__test__/player-renderer.teleport.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T05:05:35.8620703Z apps/client test:  [32m✓[39m src/__test__/player-renderer-spawn-delay.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 21[2mms[22m[39m
2026-05-16T05:05:36.5615549Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T05:05:37.3559235Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 92[2mms[22m[39m
2026-05-16T05:05:38.0824062Z apps/client test:  [32m✓[39m src/__test__/nameplate-color.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 33[2mms[22m[39m
2026-05-16T05:05:38.7991601Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:39.4986369Z apps/client test:  [32m✓[39m src/__test__/room-renderer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:40.2677759Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 78[2mms[22m[39m
2026-05-16T05:05:41.0347115Z apps/client test:  [32m✓[39m src/__test__/esc-menu.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 80[2mms[22m[39m
2026-05-16T05:05:41.7363039Z apps/client test:  [32m✓[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T05:05:42.4962075Z apps/client test:  [32m✓[39m src/__test__/background-renderer.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 84[2mms[22m[39m
2026-05-16T05:05:43.2012711Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:43.8947470Z apps/client test:  [32m✓[39m src/__test__/sprite-state-rate.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:44.5932265Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T05:05:45.2996693Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher-shift.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:46.0042083Z apps/client test:  [32m✓[39m src/__test__/boot-font-gate.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:46.7176434Z apps/client test:  [32m✓[39m src/__test__/legacy-origin.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T05:05:47.4207754Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T05:05:48.1084224Z apps/client test:  [32m✓[39m src/__test__/room-collision-bottom-edge.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T05:05:48.8016207Z apps/client test:  [32m✓[39m src/__test__/depth-set.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T05:05:49.5249424Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T05:05:50.2253562Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T05:05:50.9025256Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T05:05:50.9253345Z apps/client test: [2m Test Files [22m [1m[32m31 passed[39m[22m[90m (31)[39m
2026-05-16T05:05:50.9258390Z apps/client test: [2m      Tests [22m [1m[32m216 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (220)[39m
2026-05-16T05:05:50.9259869Z apps/client test: [2m   Start at [22m 05:05:24
2026-05-16T05:05:50.9262293Z apps/client test: [2m   Duration [22m 26.08s[2m (transform 902ms, setup 68ms, collect 1.64s, tests 1.13s, environment 15.16s, prepare 2.98s)[22m
2026-05-16T05:05:51.0656008Z apps/client test: Done
2026-05-16T05:05:51.0764893Z 
2026-05-16T05:05:51.0765748Z verify-phase-4: OK (12 steps green)
